#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
文件名称: report_api.py
功能说明:
    报表生成与导出接口，负责处理报表请求、构建表头、分页和导出功能。
    依赖于analysis_api模块获取统计聚合数据。
"""

from flask import Blueprint, request, jsonify, current_app, send_file
from io import BytesIO
from openpyxl import Workbook
from openpyxl.styles import Alignment, numbers
import json
import datetime
import traceback
from sqlalchemy import and_

from backend.api.analysis_api import aggregate_query_data
from backend.models.student_extension import StudentExtension
from backend.models.student import Student
from backend.infrastructure.database import db
from backend.config.config_manager import ConfigManager
from backend.services.analysis_display_service import AnalysisDisplayService
from backend.services.cache_manager import cache_manager
from flask_jwt_extended import jwt_required, get_jwt_identity

report_api = Blueprint("report_api", __name__)

# 初始化配置管理器（遵循三层架构）
config_manager = ConfigManager()

# 初始化显示格式化服务
display_service = AnalysisDisplayService(config_manager)

# 🔧 统一配置：复用REPORT_ROLE_FIELD_CONFIG，避免重复配置
# 通过角色化字段配置获取统计指标字段，确保字段定义的一致性
REPORT_ROLE_CONFIG = config_manager.get_report_role_field_config()
METRIC_FIELDS = REPORT_ROLE_CONFIG.get("metric_fields", {})
GROUP_FIELDS = REPORT_ROLE_CONFIG.get("group_fields", {})
FILTER_FIELDS = REPORT_ROLE_CONFIG.get("filter_fields", {})

# 🔧 保留必要的独立配置（这些配置在REPORT_ROLE_FIELD_CONFIG中没有对应项）
FIELD_DISPLAY_MAPPING = config_manager.get_config("FIELD_DISPLAY_MAPPING", {})
# 🔧 修复：统一使用FIELD_DISPLAY_MAPPING，删除FIELD_LABEL_MAPPING别名
FIELD_DISPLAY_MAPPING = config_manager.get_config("FIELD_DISPLAY_MAPPING", {})
complete_fields = config_manager.get_config("COMPLETE_FIELDS", [])

# 三层表头生成逻辑已迁移到 AnalysisDisplayService.build_multi_level_header
# 原有 build_multi_level_header 函数已删除，使用 display_service.build_multi_level_header 替代

# Excel导出逻辑已迁移到 AnalysisDisplayService.export_to_excel
# 原有 export_to_excel 函数已删除，使用 display_service.export_to_excel 替代

@report_api.route("/api/report/generate", methods=["GET"])
@jwt_required()
def generate_report():
    """
    生成统计报表接口
    ---
    tags:
      - Reports
    parameters:
      - name: query_mode
        in: query
        type: string
        enum: [template, custom]
        default: template
        description: 查询模式(template-模板/custom-自定义)
      - name: template
        in: query
        type: string
        enum: [template1, template2]
        description: 模板名称(当query_mode=template时必填)
    responses:
      200:
        description: 报表数据或导出文件
    """
    try:
        # 记录请求开始
        current_app.logger.info(
            f"报表请求开始 - 模式: {request.args.get('query_mode')}, "
            f"模板: {request.args.get('template')}, "
            f"IP: {request.remote_addr}"
        )
        
        # 1. 请求参数解析
        template = request.args.get("template", "").strip()
        advanced_str = request.args.get("advanced_conditions", "").strip()
        query_mode = request.args.get("query_mode", "template").strip()
        stat_time = request.args.get("stat_time", "").strip()
        report_name = request.args.get("report_name", "").strip()
        
        try:
            page = int(request.args.get("page", 1))
        except ValueError:
            page = 1
            
        try:
            per_page = int(request.args.get("per_page", 10))
        except ValueError:
            per_page = 10
            
        # 🔧 调试：打印分页参数
        # 2. 处理 stat_time 参数 —— 单独获取 data_year，advanced_str 保持原有高级条件
        data_year = stat_time or None

        # 3. 调用聚合函数 —— 传递 data_year 和 advanced_str
        
        # ========== 优先检查缓存数据（来自图表页面跳转）==========
        cache_key_param = request.args.get('cache_key', '').strip()
        from_chart = request.args.get('from_chart') == 'true'
        
        if cache_key_param and from_chart:
            try:
                current_user_id = get_jwt_identity()
                
                # 从缓存获取聚合数据
                aggregated_data = cache_manager.get_and_refresh(cache_key_param, current_user_id)
                
                if aggregated_data:
                    # 为返回图表页面缓存数据
                    return_cache_key = cache_manager.store_data(
                        user_id=current_user_id,
                        aggregated_data=aggregated_data,
                        source_type='report'
                    )
                    
                    # 跳转到响应构建逻辑
                    cache_key = return_cache_key
                    
                else:
                    # 继续执行正常查询
                    aggregated_data = aggregate_query_data(
                        None, query_mode, template, data_year, advanced_str
                    )
                    
            except Exception as cache_error:
                current_app.logger.warning(f"缓存读取失败，执行正常查询: {cache_error}")
                # 继续执行正常查询
                aggregated_data = aggregate_query_data(
                    None, query_mode, template, data_year, advanced_str
                )
        else:
            # 执行正常聚合查询
            aggregated_data = aggregate_query_data(
                None, query_mode, template, data_year, advanced_str
            )
        
        # 🔧 新增：缓存聚合数据以支持跳转到图表页面（仅在非缓存获取情况下）
        if not (cache_key_param and from_chart and cache_key):
            # 只有在没有从缓存获取数据时才进行新的缓存
            try:
                # 使用当前登录用户
                current_user_id = get_jwt_identity()
                
                if not from_chart:
                    # 新查询：清理旧缓存并存储新数据
                    cache_manager.cleanup_user_cache(current_user_id)
                
                # 缓存聚合数据
                cache_key = cache_manager.store_data(
                    user_id=current_user_id,
                    aggregated_data=aggregated_data,
                    source_type='report'
                )
                        
            except Exception as cache_error:
                current_app.logger.warning(f"缓存操作失败: {cache_error}")
        
        data_rows = aggregated_data.get("data_rows", [])
        dynamic_metrics = aggregated_data.get("dynamic_metrics", [])
        free_group_field = aggregated_data.get("free_group_field", "")
        records = aggregated_data.get("records", [])

        # 4. 分页处理
        total_items = len(records)
        start_idx = (page - 1) * per_page
        end_idx = start_idx + per_page
        paged_rows = data_rows[start_idx:end_idx]
        
        # 🔧 调试：打印分页信息
        current_app.logger.debug(f"分页信息: total_items={total_items}, page={page}, per_page={per_page}")
        current_app.logger.debug(f"分页范围: start_idx={start_idx}, end_idx={end_idx}")
        current_app.logger.debug(f"分页后数据行数: {len(paged_rows)}")

        # 5. 构造多层表头
        # 🔧 修复：正确获取字段显示名称
        if free_group_field:
            # 从全局字段配置表获取显示名称
            group_title = config_manager.get_report_field_display_name(free_group_field)
        else:
            group_title = "分组"
        
        # 🔧 调试：打印表头信息
        current_app.logger.debug(f"free_group_field: {free_group_field}")
        current_app.logger.debug(f"group_title: {group_title}")
        current_app.logger.debug(f"dynamic_metrics: {dynamic_metrics}")
        
        header = display_service.build_multi_level_header(dynamic_metrics, group_title)
        
        # 🔧 调试：打印表头结构
        current_app.logger.debug(f"生成的表头结构: {header}")

        # 6. 构造报表名称与筛选附注
        if query_mode == "template":
            final_report_name = f"{stat_time}-学生视力统计表"
        else:
            final_report_name = report_name if report_name else "统计报表"
            
        filters_annotation = []
        if stat_time:
            filters_annotation.append(f"统计时间: {stat_time}")
        if query_mode != "template" and advanced_str:
            try:
                adv_conds = json.loads(advanced_str)
                for cond in adv_conds:
                    if cond.get("role", "").strip().lower() == "filter":
                        field_disp = config_manager.get_field_display_mapping().get(
                            cond.get("field", "").strip(),
                            cond.get("field", "").strip()
                        )
                        filters_annotation.append(f"{field_disp}: {cond.get('value')}")
            except Exception as exc:
                current_app.logger.error(f"解析筛选附注失败: {str(exc)}")
        annotation = " ".join(filters_annotation)

        # 7. 构造响应数据
        response = {
            "tableName": final_report_name,
            "filterAnnotation": annotation,
            "header": header,
            "rows": paged_rows,
            "total": total_items
        }
        
        # 🔧 新增：添加缓存键以支持跳转功能
        if cache_key:
            response["cache_key"] = cache_key
        
        # 🔧 调试：打印响应数据
        current_app.logger.debug(f"构造的响应数据: {response}")
        current_app.logger.debug(f"响应数据大小: tableName={len(final_report_name)}, filterAnnotation={len(annotation)}")
        current_app.logger.debug(f"响应数据行数: {len(paged_rows)}")

        # 处理导出请求
        export_flag = request.args.get("export", "").strip().lower() == "true"
        if export_flag:
            try:
                output = display_service.export_to_excel(header, data_rows, f"{final_report_name}.xlsx")
                current_app.logger.info(f"成功导出报表: {final_report_name}.xlsx")
                return send_file(
                    output,
                    as_attachment=True,
                    download_name=f"{final_report_name}.xlsx",
                    mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                )
            except Exception as exc:
                current_app.logger.error(f"导出报表失败: {str(exc)}", exc_info=True)
                return jsonify({"error": "导出报表失败"}), 500

        current_app.logger.info(f"报表生成成功 - 记录数: {len(data_rows)}")
        
        # ▼▼▼ 修复：确保所有路径都有返回值 ▼▼▼
        return jsonify(response)
        # ▲▲▲ 修复结束 ▲▲▲
        
    except Exception as exc:
        current_app.logger.error(
            f"报表生成异常 - 错误: {str(exc)}\n参数: {dict(request.args)}", 
            exc_info=True
        )
        return jsonify({"error": str(exc)}), 500